package ar.com.ironsoft.javaopenauth.utils;

import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import ar.com.ironsoft.javaopenauth.exceptions.UnregisteredActionException;
import ar.com.ironsoft.javaopenauth.exceptions.UnregisteredException;
import ar.com.ironsoft.javaopenauth.exceptions.UnregisteredServiceException;
import ar.com.ironsoft.javaopenauth.oauth.OAuthService;

/**
 * Util class to work with servlets and urls.
 * 
 * @author Tomas de Priede
 * @version 0.1.3, 05/04/2011
 * @since 0.1.2-SNAPSHOT
 */
public class ServletUtils {

	/**
	 * Return the service name from the uri, with the configured servlet.<br />
	 * Example: <br />
	 * You configure a oauth servlet with name oauth. <br />
	 * Then you must use the following uri: <br/>
	 * /oauth/<strong>service</strong>/action <br />
	 * <br />
	 * Then the "service" will be returned
	 * 
	 * @param oauthServlet
	 *            the servlet name
	 * @param uri
	 *            the request uri
	 * @return the service name
	 * @author Tomas de Priede
	 * @version 0.1.3, 05/04/2011
	 * @since 0.1.2-SNAPSHOT
	 * @see ar.com.ironsoft.javaopenauth.utils.ServletUtils#extractServiceAndActionFromURI(String,String)
	 */
	public static String getServiceFromURI(String oauthServlet, String uri) {
		return extractServiceAndActionFromURI(oauthServlet, uri)[0];
	}

	/**
	 * Return the service and action name from the uri, with the configured
	 * servlet.<br />
	 * Example: <br />
	 * You configure a oauth servlet with name oauth. <br />
	 * Then you must use the following uri: <br/>
	 * /oauth/<strong>service</strong>/<strong>action</strong> <br />
	 * <br />
	 * Then the "service" and "action" will be returned
	 * 
	 * @param oauthServlet the servlet name
	 * @param uri the request uri
	 * @return the service and the action name
	 * @author Tomas de Priede
	 * @version 0.1.3, 05/04/2011
	 * @since 0.1.2-SNAPSHOT
	 */
	private static String[] extractServiceAndActionFromURI(String oauthServlet,
			String uri) {
		ValidatorUtils.validateNullOrEmpty(oauthServlet, uri);
		if (!StringUtils.contains(uri, oauthServlet + "/")) {
			throw new UnregisteredException(
					"Servlet name does not matches with redirect uri");
		}
		String[] splitted = StringUtils.splitByWholeSeparator(uri, oauthServlet
				+ "/");

		if (!StringUtils.contains(splitted[splitted.length - 1], "/")) {
			throw new UnregisteredActionException("No action name passed");
		}

		return StringUtils.split(splitted[splitted.length - 1], "/");
	}

	/**
	 * Return the action name from the uri, with the configured servlet.<br />
	 * Example: <br />
	 * You configure a oauth servlet with name oauth. <br />
	 * Then you must use the following uri: <br/>
	 * /oauth/service/<strong>action</strong> <br />
	 * <br />
	 * Then the "action" will be returned
	 * 
	 * @param oauthServlet
	 *            the servlet name
	 * @param uri
	 *            the request uri
	 * @return the service name
	 * @author Tomas de Priede
	 * @version 0.1.3, 05/04/2011
	 * @since 0.1.2-SNAPSHOT
	 * @see ar.com.ironsoft.javaopenauth.utils.ServletUtils#extractServiceAndActionFromURI(String,String)
	 */
	public static String getActionFromURI(String oauthServlet, String uri) {
		String[] res = extractServiceAndActionFromURI(oauthServlet, uri);
		if (res.length < 2) {
			throw new UnregisteredActionException("No action name passed");
		}
		return res[1];
	}

	/**
	 * Checks if some service is in the registeredServicesMap. <br />
	 * If not, throws a UnregisteredServiceException.
	 * 
	 * @param service the service to evaluate
	 * @param registeredServices the map of services
	 * @author Tomas de Priede
	 * @version 0.1.2, 05/02/2011
	 * @since 0.1.2-SNAPSHOT
	 */
	public static void checkIfServiceIsRegisted(String service,
			Map<String, OAuthService> registeredServices) {
		ValidatorUtils.validateNullOrEmpty(service, registeredServices);

		if (!registeredServices.containsKey(service)) {
			throw new UnregisteredServiceException(
					"The service is not registed. Add it to the params of the JavaOpenAuth servlet");
		}
	}

	/**
	 * Checks if some action is in the registeredActions set. <br />
	 * If not, throws a UnregisteredActionException.
	 * 
	 * @param action the action to evaluate
	 * @param registeredActions the set of actions
	 * @author Tomas de Priede
	 * @version 0.1.2, 05/02/2011
	 * @since 0.1.2-SNAPSHOT
	 */
	public static void checkIfActionIsRegisted(String action,
			Set<ServletActionType> registeredActions) {
		ValidatorUtils.validateNullOrEmpty(action, registeredActions);

		if (!registeredActions.contains(ServletActionType.buildEnum(action))) {
			throw new UnregisteredActionException(
					"You are calling an invalid action for the service");
		}
	}
}
